package com.suning.sawp.service.impl.register;

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.base.Charsets;
import com.google.gson.Gson;
import com.suning.framework.vcsms.client.entity.Result;
import com.suning.rsf.consumer.ServiceLocator;
import com.suning.sawp.constants.ConfigConstants;
import com.suning.sawp.constants.RegAndBindErrCodeConstants;
import com.suning.sawp.constants.SMSErrCodeConstants;
import com.suning.sawp.dto.common.ReturnMsg;
import com.suning.sawp.dto.customer.CustInfoDetailDto;
import com.suning.sawp.dto.esb.LocateMemberInfo;
import com.suning.sawp.dto.register.LocateMemberRtn;
import com.suning.sawp.dto.register.NewRedInfoRtn;
import com.suning.sawp.dto.register.RegisterInfoRtn;
import com.suning.sawp.intf.esb.MemberInfoService;
import com.suning.sawp.intf.register.RegisterService;
import com.suning.sawp.intf.sms.SmsService;
import com.suning.sawp.po.customer.ClerkCustInfo;
import com.suning.sawp.service.impl.customer.ClerkCustRelService;
import com.suning.sawp.service.util.DJStringUtils;
import com.suning.sawp.service.util.HttpClientUtil;
import com.suning.sawp.service.util.PBECoder;
import com.suning.sawp.service.util.SCMConfigUtil;
import com.suning.srs.rsfservice.dto.CrtOfflineAcnt;
import com.suning.srs.rsfservice.dto.CrtOnlineAndOfflineAcnt;
import com.suning.srs.rsfservice.dto.OfflineContactPoint;
import com.suning.srs.rsfservice.dto.OfflineIndividualInfo;
import com.suning.srs.rsfservice.dto.OnlineAndOfflineContactPoint;
import com.suning.srs.rsfservice.dto.OnlineAndOfflineIndividualInfo;
import com.suning.srs.rsfservice.dto.RegResult;
import com.suning.srs.rsfservice.service.UserRegisterService;
import com.suning.vgs.follow.remote.intf.StoreConsumerService;
import com.suning.vgs.follow.remote.intf.StoreManRemoteService;
import com.suning.vgs.follow.remote.store.ClerkCustomerDevRetDto;
import com.suning.vgs.follow.remote.store.ConsumerBehaviorDto;
import com.suning.vgs.follow.remote.store.ConsumerBehaviorType;
import com.suning.vgs.follow.remote.store.StoreManEbuyAccount;

/**
 * 
 * 注册和绑定会员实现类<br> 
 * 〈功能详细描述〉
 *
 * @author 12061818
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service
public class RegisterServiceImpl implements RegisterService {
	private static final Logger LOGGER = LoggerFactory.getLogger(RegisterServiceImpl.class);

	private static final String SMS_SEND_SCENEID = "WECHAT-M-007";
	
	/**
	 * 默认门店编码
	 */
	private static final String DEF_STORE_CODE = "7320";
	
	/**
     * 默认分公司编码
     */
	private static final String DEF_BRANCH_CODE = "3600";
	
	@Autowired
	MemberInfoService memberInfoService;
	
	@Autowired
	SmsService smsService;
	
	@Autowired
	StoreConsumerService storeConsumerService;
	
	/**
	 * follow 保存用户发展用户信息接口
	 */
	@Resource
	StoreManRemoteService storeManRemoteService;
	
	private String validateNewRedUrl;
	
	UserRegisterService userRegisterService = ServiceLocator.getService(UserRegisterService.class, null);
	
	@Resource
	ClerkCustRelService clerkCustRelService;
	
	public ReturnMsg<LocateMemberRtn> locateMemberByMobileNo(String mobileNo) {
		ReturnMsg<LocateMemberRtn> ret = new ReturnMsg<LocateMemberRtn>();
		LocateMemberRtn memberRtn = new LocateMemberRtn();
		LocateMemberInfo memberInfo = null;
		try {
			memberInfo = memberInfoService.locateMemberByMobileNo(mobileNo);
		} catch (Exception e){
			ret.setRetFlag(ReturnMsg.FAIL);
	    	ret.setErrorCode(RegAndBindErrCodeConstants.COMMON_ERR_E999);
	    	ret.setErrorMessage(RegAndBindErrCodeConstants.COMMON_ERR_MAP
	    			.get(RegAndBindErrCodeConstants.COMMON_ERR_E999));
	    	Object[] errArgs = {mobileNo, e};
	    	LOGGER.error("会员验证发生异常:mobile:{}, error:{}", errArgs);
	    	return ret;
		}

		if (null == memberInfo) {
			ret.setRetFlag(ReturnMsg.FAIL);
			ret.setErrorCode(RegAndBindErrCodeConstants.MEMBER_ERR_E001);
	    	ret.setErrorMessage(RegAndBindErrCodeConstants.MEMBER_ERR_MAP
	    			.get(RegAndBindErrCodeConstants.MEMBER_ERR_E001));
			LOGGER.error("未定位出会员信息,定位出错,mobileNo:{}", mobileNo);
			return ret;
		} else {
			if (StringUtils.isNotBlank(memberInfo.getCustNum())){
				String flag = isGetNewRed(memberInfo.getCustNum());
				if (StringUtils.isNotBlank(flag) && !("null".equals(flag))){
					//可以领取新人红包
					if ("allowed".equals(flag)){
						memberRtn.setRedPacketStatus(LocateMemberRtn.NOT_GET_REDPACK);
					}//不可以领取新人红包 
					else if ("unallowed".equals(flag)){
						memberRtn.setRedPacketStatus(LocateMemberRtn.HAS_GET_REDPACK);
					}//查询状态失败返回无状态  0 
					else {
						memberRtn.setRedPacketStatus(LocateMemberRtn.RESULT_NULL);
					}
				}
			} else {
				//还不是会员,可以领取新人红包  
				memberRtn.setRedPacketStatus(LocateMemberRtn.NOT_GET_REDPACK);
			}
			
			// 已经是线下会员卡
			if (StringUtils.isNotBlank(memberInfo.getCardNo()) 
					&& StringUtils.isBlank(memberInfo.getCustNum())) {
				memberRtn.setRegisterStatus(LocateMemberRtn.NOT_ONLINE_MEMBER);
			}// 已经是线上会员卡
			else if (StringUtils.isNotBlank(memberInfo.getCustNum())
					&& StringUtils.isBlank(memberInfo.getCardNo())) {
				memberRtn.setRegisterStatus(LocateMemberRtn.NOT_OFFLINE_MEMBER);
			}// 已经是融合会员
			else if (StringUtils.isNotBlank(memberInfo.getCardNo())
					&& StringUtils.isNotBlank(memberInfo.getCustNum())) {
				memberRtn.setRegisterStatus(LocateMemberRtn.IS_MEMBER);
			}// 既不是线上会员也不是线下会员
			else {
				memberRtn.setRegisterStatus(LocateMemberRtn.NOT_ONLINEANDOFFLINE_MEMBER);
			}
			ret.setData(memberRtn);
			Object[] argsArr = {memberInfo.isSuccess(), mobileNo,
					memberInfo.getCardNo(), memberInfo.getCustNum()};
			LOGGER.info("查询会员状态信息, result:{}, mobileNo:{}, cardNo:{}, custNum:{}", argsArr);
		}
		return ret;
	}
	
	@SuppressWarnings("rawtypes")
	public ReturnMsg sendShortMessageToUser(String mobileNo, String requestIp) {
		Object[] argsArr = { mobileNo};
		LOGGER.info("发送短信验证码,mobileNo:{}", argsArr);
		ReturnMsg rtnMsg = new ReturnMsg();
		// 获得短信验证码
		try {
			Result resBean = smsService.generateSmsCode(mobileNo, requestIp,
					SMS_SEND_SCENEID);
			// 记录返回的验证码信息
			Object[] resArr = {mobileNo, resBean.getCode(), resBean.getErrcode(),
					resBean.getRestNum(), resBean.getResult() };
			LOGGER.info("返回短信验证码信息是:mobileNo={},code={},errCode={},restNum={},result={}",
					resArr);

			// 判断是否成功
			if (resBean.getErrcode().equals(SMSErrCodeConstants.CODE_1001)) {
				rtnMsg.setRetFlag(ReturnMsg.SUCCESS);
			}
			// 请尝试一分钟后获取验证码
			else if (resBean.getErrcode().equals(SMSErrCodeConstants.CODE_10002)) {
				rtnMsg.setRetFlag(ReturnMsg.FAIL);
				rtnMsg.setErrorCode(SMSErrCodeConstants.CODE_10002);
				rtnMsg.setErrorMessage(SMSErrCodeConstants.getValue(SMSErrCodeConstants.CODE_10002));
			}
			// 该手机号今天无法再获取验证码
			else if (resBean.getErrcode().equals(SMSErrCodeConstants.CODE_10001)) {
				rtnMsg.setRetFlag(ReturnMsg.FAIL);
				rtnMsg.setErrorCode(SMSErrCodeConstants.CODE_10001);
				rtnMsg.setErrorMessage(SMSErrCodeConstants.getValue(SMSErrCodeConstants.CODE_10001));
			}
			// 用户注册次数过多
			else if (resBean.getErrcode().equals(SMSErrCodeConstants.CODE_10003)) {
				rtnMsg.setRetFlag(ReturnMsg.FAIL);
				rtnMsg.setErrorCode(SMSErrCodeConstants.CODE_10003);
				rtnMsg.setErrorMessage(SMSErrCodeConstants.getValue(SMSErrCodeConstants.CODE_10003));
			} else {
				LOGGER.error("ScreenInsuranceController 验证码平台返回错误");
				rtnMsg.setRetFlag(ReturnMsg.FAIL);
				rtnMsg.setErrorCode(SMSErrCodeConstants.FAILURE);
				rtnMsg.setErrorMessage("验证码获得失败，请稍后再试!");
			}
		} catch (Exception e) {
			LOGGER.error("发送短消息失败,mobileNo:{}, ERROR:{}", mobileNo, e);
			rtnMsg.setRetFlag(ReturnMsg.FAIL);
			rtnMsg.setErrorCode(SMSErrCodeConstants.FAILURE);
			rtnMsg.setErrorMessage("发送短信失败");
		}
		return rtnMsg;
	}
	
	public ReturnMsg<RegisterInfoRtn> createOfflineAccount(String staffCode,
			String deviceType, String mobileNo, String validCode, String channel) {
		ReturnMsg<RegisterInfoRtn> ret = new ReturnMsg<RegisterInfoRtn>();
		RegisterInfoRtn regisRtn = new RegisterInfoRtn();
		// 校验短信
		Result validResult = this.smsService.validateSmsCode(mobileNo, validCode, "0", SMS_SEND_SCENEID);
		String regChannel = getRegisterChannel(deviceType);
		LocateMemberInfo memberInfo = memberInfoService.locateMemberByMobileNo(mobileNo);
		
		String storeCode = null;
		// 验证成功
		if (SMSErrCodeConstants.CODE_1002.equals(validResult.getErrcode())) {
			storeCode = storeManRemoteService.getStoreCodeByStaffId(staffCode);
			//默认门店编码
			if (StringUtils.isBlank(storeCode) || "null".equals(storeCode)) {
				storeCode = DEF_STORE_CODE;
			}
			String branchCode = storeManRemoteService.getBranchCodeByStoreCode(storeCode);
			//默认门店编码，分公司编码
			if (StringUtils.isBlank(branchCode) || "null".equals(branchCode)) {
				branchCode = DEF_BRANCH_CODE;
				storeCode = DEF_STORE_CODE;
			}
			CrtOfflineAcnt ca = createOfflineAccountParam(staffCode, storeCode,
					branchCode, memberInfo, regChannel);
			RegResult reg = userRegisterService.createOfflineAccount(ca);
			if (null != reg) {
			    regisRtn.setCardNo(reg.getCardNo());
	            regisRtn.setCustNum(reg.getCustNum());
	            
	            Object[] argsArr = {reg.getCode(), mobileNo, staffCode, 
	                    storeCode, branchCode, reg.getMessage(), regChannel, 
	                    reg.getCardNo(), reg.getCustNum()};
	            LOGGER.info("通过线上会员卡注册线下会员, result:{}, mobileNo{}, staffCode:{}, " +
	                    "storeCode:{}, branchCode:{}, message:{}, channel:{}, cardNo:{}, custNum:{}",argsArr);
			}
			
			// 返回会员不存在的错误，门店分公司给默认值
			RegResult defReg = null;
			if (null != reg && "E4700705".equals(reg.getCode())) {
				String defStoreCode = DEF_STORE_CODE;
				String defBranchCode = DEF_BRANCH_CODE;
				storeCode = defStoreCode;
				CrtOfflineAcnt defCa = createOfflineAccountParam(staffCode,
						defStoreCode, defBranchCode, memberInfo, regChannel);
				defReg = userRegisterService.createOfflineAccount(defCa);
				regisRtn.setCardNo(defReg.getCardNo());
				regisRtn.setCustNum(defReg.getCustNum());
				
				Object[] defArgsArr = {defReg.getCode(), mobileNo, staffCode, 
						defStoreCode, defBranchCode, defReg.getMessage(), 
						regChannel, defReg.getCardNo(), defReg.getCustNum()};
				LOGGER.info("通过线上会员卡注册线下会员, result:{}, mobileNo:{}, staffCode:{}, defStoreCode:{}, defBranchCode:{}, " +
						"defMessage:{}, channel:{}, cardNo:{}, custNum:{}",
						defArgsArr);
			}
			
			//注册成功
			if (null != reg && "COMPLETE".equals(reg.getCode())){
				ret.setRetFlag(ReturnMsg.SUCCESS);
				ret.setData(regisRtn);
				bindStaffAndUser(staffCode, mobileNo, reg.getCustNum(), channel, storeCode);
				//会员消费行为采集
				saveConsumBehavior(regisRtn, staffCode, mobileNo);
			} else if (null != defReg && "COMPLETE".equals(defReg.getCode())){
				ret.setRetFlag(ReturnMsg.SUCCESS);
				ret.setData(regisRtn);
				bindStaffAndUser(staffCode, mobileNo, reg.getCustNum(), channel, storeCode);
				//会员消费行为采集
				saveConsumBehavior(regisRtn, staffCode, mobileNo);
			}//注册失败 
			else{
        		Object[] errArgs = {reg == null ? "Null" : reg.getCode(), mobileNo, staffCode, 
        				storeCode, branchCode, reg == null ? "Null" : reg.getMessage(), regChannel};
                LOGGER.error("通过线上会员卡注册线下会员失败, result:{}, mobileNo:{}, staffCode:{}," +
                		" storeCode:{}, branchCode:{}, message:{}, channel:{}", errArgs);
                ret.setRetFlag(ReturnMsg.FAIL);
                ret.setErrorCode(reg == null ? "" : reg.getCode());
                ret.setErrorMessage(RegAndBindErrCodeConstants.REG_ERR_MAP
    	    			.get(RegAndBindErrCodeConstants.REG_ERR_E003));
			}
			
		}// 达到最大容错次数
		else if (validResult.getErrcode().equals(SMSErrCodeConstants.CODE_1103)) {
			ret.setRetFlag(ReturnMsg.FAIL);
			ret.setErrorCode(RegAndBindErrCodeConstants.REG_ERR_E001);
			ret.setErrorMessage(RegAndBindErrCodeConstants.REG_ERR_MAP
	    			.get(RegAndBindErrCodeConstants.REG_ERR_E001));
		}// 验证码验证失效,需要重新验证
		else {
			ret.setRetFlag(ReturnMsg.FAIL);
			ret.setErrorCode(RegAndBindErrCodeConstants.REG_ERR_E002);
			ret.setErrorMessage(RegAndBindErrCodeConstants.REG_ERR_MAP
	    			.get(RegAndBindErrCodeConstants.REG_ERR_E002));
		}
		return ret;
	}
	
	public ReturnMsg<RegisterInfoRtn> createOnlineAndOfflineAccount(
			String staffCode, String deviceType, String mobileNo,
			String validCode, String channel) {
		ReturnMsg<RegisterInfoRtn> ret = new ReturnMsg<RegisterInfoRtn>();
		RegisterInfoRtn regisRtn = new RegisterInfoRtn();
		// 校验短信
		Result validResult = this.smsService.validateSmsCode(mobileNo,validCode, "0", SMS_SEND_SCENEID);
		String regChannel = getRegisterChannel(deviceType);
		
		String storeCode = null;
		// 验证成功
		if (SMSErrCodeConstants.CODE_1002.equals(validResult.getErrcode())) {
			storeCode = storeManRemoteService.getStoreCodeByStaffId(staffCode);
			//默认门店编码
			if (StringUtils.isBlank(storeCode) || "null".equals(storeCode)) {
				storeCode = DEF_STORE_CODE;
			}
			String branchCode = storeManRemoteService.getBranchCodeByStoreCode(storeCode);
			//默认门店编码，分公司编码
			if (StringUtils.isBlank(branchCode) || "null".equals(branchCode)) {
				branchCode = DEF_BRANCH_CODE;
				storeCode = DEF_STORE_CODE;
			}
			CrtOnlineAndOfflineAcnt param = createOnlineAndOfflineAccountParam(
					staffCode, mobileNo, storeCode, branchCode, regChannel);
			RegResult reg = userRegisterService.createOnlineAndOfflineAccount(param);
			
			if (null != reg) {
			    regisRtn.setCardNo(reg.getCardNo());
	            regisRtn.setCustNum(reg.getCustNum());
	            
	            Object[] infoArgs = {reg.getCode(), mobileNo, staffCode,
	                    storeCode, branchCode, reg.getMessage(), regChannel, reg.getCustNum(), 
	                    reg.getCardNo()};
	            LOGGER.info("注册线上线下会员, result:{}, mobileNo:{}, staffCode:{}, storeCode:{}, " +
	                    "branchCode:{}, message:{}, channel:{}, custNo:{}, cardNo:{}", infoArgs);
			}
			
			// 返回会员不存在的错误，门店分公司给默认值
			RegResult defReg = null;
			if (null != reg && "E4700705".equals(reg.getCode())) {
				String defStoreCode = DEF_STORE_CODE;
				String defBranchCode = DEF_BRANCH_CODE;
				storeCode = defStoreCode;
				
				CrtOnlineAndOfflineAcnt defParam = createOnlineAndOfflineAccountParam(
						staffCode, mobileNo, defStoreCode, defBranchCode, regChannel);
				defReg = userRegisterService.createOnlineAndOfflineAccount(defParam);
				regisRtn.setCardNo(defReg.getCardNo());
				regisRtn.setCustNum(defReg.getCustNum());
				
				Object[] defInfoArgs = {defReg.getCode(), mobileNo, 
						staffCode, defStoreCode, defBranchCode, defReg.getMessage(), regChannel,
						reg.getCustNum(), defReg.getCardNo()};
				LOGGER.info("注册线上线下会员, result:{}, mobileNo:{}, staffCode:{}, " +
						"defStoreCode:{}, defBranchCode:{}, defMessage:{}, channel:{}," +
						" custNo:{}, cardNo:{}", defInfoArgs);
			}
			
			//注册成功
			if (null != reg && "COMPLETE".equals(reg.getCode())){
				ret.setRetFlag(ReturnMsg.SUCCESS);
				ret.setData(regisRtn);
				bindStaffAndUser(staffCode, mobileNo, reg.getCustNum(), channel, storeCode);
				//会员消费行为采集
				saveConsumBehavior(regisRtn, staffCode, mobileNo);
			} else if (null != defReg && "COMPLETE".equals(defReg.getCode())){
				ret.setRetFlag(ReturnMsg.SUCCESS);
				ret.setData(regisRtn);
				bindStaffAndUser(staffCode, mobileNo, reg.getCustNum(), channel, storeCode);
				//会员消费行为采集
				saveConsumBehavior(regisRtn, staffCode, mobileNo);
			}//注册失败 
			else{
        		Object[] errArgs = {reg == null ? "Null" : reg.getCode(), mobileNo, staffCode, 
        				storeCode, branchCode, reg == null ? "Null" : reg.getMessage(), regChannel};
                LOGGER.error("注册线上线下会员失败, result:{}, mobileNo:{}, staffCode:{}, " +
                		"storeCode:{}, branchCode:{}, message:{}, channel:{}", errArgs);
                ret.setRetFlag(ReturnMsg.FAIL);
                ret.setErrorCode(RegAndBindErrCodeConstants.REG_ERR_E003);
                ret.setErrorMessage(RegAndBindErrCodeConstants.REG_ERR_MAP
    	    			.get(RegAndBindErrCodeConstants.REG_ERR_E003));
			}
		}// 达到最大容错次数
		else if (validResult.getErrcode().equals(SMSErrCodeConstants.CODE_1103)) {
			ret.setRetFlag(ReturnMsg.FAIL);
			ret.setErrorCode(RegAndBindErrCodeConstants.REG_ERR_E001);
			ret.setErrorMessage(RegAndBindErrCodeConstants.REG_ERR_MAP
	    			.get(RegAndBindErrCodeConstants.REG_ERR_E001));
		}// 验证码验证失效,需要重新验证
		else {
			ret.setRetFlag(ReturnMsg.FAIL);
			ret.setErrorCode(RegAndBindErrCodeConstants.REG_ERR_E002);
			ret.setErrorMessage(RegAndBindErrCodeConstants.REG_ERR_MAP
	    			.get(RegAndBindErrCodeConstants.REG_ERR_E002));
		}
		return ret;
	}
	
	/**
	 * 注册成功的会员存入数据库
	 * @param staffCode 操作人工号
	 * @param account 会员手机
	 * @param custNum 会员编号
	 * @param channel 注册来源渠道
	 * @param storeCode 门店编码
	 */
	private void bindStaffAndUser(String staffCode, String account, String custNum
	        , String channel, String storeCode){
        //1、 记录店+渠道的会员注册
	    ClerkCustomerDevRetDto bean = new ClerkCustomerDevRetDto();
        bean.setClerkNo(staffCode);
        bean.setCustNo(custNum);
        bean.setChannel(channel);
        bean.setMobile(account);
        bean.setCreateTime(new Date());
        storeManRemoteService.saveBindingBetweenUserAndClerk(bean);
        //2、 通知会员，绑定店员与-新注册会员的推广关系
        // 根据工号查询对应的易购账号
        StoreManEbuyAccount ebuyAccount = storeManRemoteService.queryStoreManEbuyAccount(staffCode);
        if (null != ebuyAccount) {
            boolean bindFlag = memberInfoService.bindKGPartyToParty(ebuyAccount.getCustNo(), custNum);
            if (!bindFlag) {
                Object[] args = {staffCode, custNum};
                LOGGER.warn("RegisterService.bindKGPartyToParty fail, params:{}", args);
            }
        } else {
            LOGGER.warn("staffId:{} has not ebuy account", staffCode);
        }
        //3、 加入客户关系表
        // 如果门店编码为默认门店编码，且注册来源为一键注册，因为无法分辨此会员是否为该门店真实员工注册，舍弃此条记录不计入店员客户关系表中
        if (!(DEF_STORE_CODE.equals(storeCode) && ClerkCustInfo.CustSource.ONE_KEY_REG.equals(channel))) {
            Long rateId = Long.valueOf(SCMConfigUtil.getConfig(ConfigConstants.DEFAULT_RATE_ID));
            CustInfoDetailDto detailDto = new CustInfoDetailDto();
            // 客户评级给C
            detailDto.setRateId(rateId);
            // 会员编码
            detailDto.setCustNo(custNum);
            // 客户来源
            detailDto.setCustSource(channel);
            // 非重点客户
            detailDto.setIsKeyCust(ClerkCustInfo.KeyCustOpType.CANCEL_KEY);
            // 手机号
            detailDto.setMobile(account);
            // 工号
            detailDto.setStaffId(staffCode);
            // 门店编码
            detailDto.setStoreCode(storeCode);
            // 记录创建时间
            detailDto.setCreateTime(new Date());
            // 备注名，注册为手机号，以脱敏手机号作为用户名
            detailDto.setRemarkName(DJStringUtils.desensitiseMobile(account));
            clerkCustRelService.addClerkCustRelWhenNoOutGrow(detailDto);
        }
	}
	
	/**
	 * 判断是否领取了新人红包
	 * @param custNum
	 * @return
	 */
	private String isGetNewRed(String custNum){
		LOGGER.info("开始查询红包领取状态，custNum:{}",custNum);
		try{
			String encryptedCustNum = encryptCustNum(custNum);
			String data = HttpClientUtil.getData(validateNewRedUrl + "?custNum=" + encryptedCustNum);
			Gson gson = new Gson();
			NewRedInfoRtn redInfo = gson.fromJson(data, NewRedInfoRtn.class);
			return redInfo.getAllowFlag();
		} catch (Exception e){
			LOGGER.error("查询新人领取红包状态发生异常,custNum:{}, error:{}", custNum, e);
			//发生异常了返回状态 0
			return "0";
		}
	}
	
	/**
	 * 构造有线上会员卡的直接绑定 线下会员方法所需参数
	 * 
	 * @param staffCode
	 * @param storeCode
	 * @param branchCode
	 * @param memberInfo
	 * @return
	 */
	private CrtOfflineAcnt createOfflineAccountParam(String staffCode,
			String storeCode, String branchCode, LocateMemberInfo memberInfo,
			String accountCreatedChannel) {
		CrtOfflineAcnt ca = new CrtOfflineAcnt();
		OfflineContactPoint contactPonit = new OfflineContactPoint();
		OfflineIndividualInfo info = new OfflineIndividualInfo();
		List<OfflineContactPoint> contactPointList = new ArrayList<OfflineContactPoint>();
		// 1：“ip/门店”说明：POS需要填“门店”，B2C业态则要填“IP”
		// 2：“操作员工号”说明：B2C采用账号，POS采用员工号
		// 3：@@为分割符
		ca.setRequestIP(storeCode + "@@" + staffCode);
		// 业态类型 电器
		ca.setEcoType("140000000020");
		ca.setCustNum(memberInfo.getCustNum());
		ca.setStore(storeCode);
		ca.setBranch(branchCode);
		ca.setAccountCreatedChannel(accountCreatedChannel);
		contactPonit.setCntctPointType("143000000010");
		contactPonit.setPreferFlag("100000000010");
		contactPointList.add(contactPonit);
		info.setContactPointList(contactPointList);
		ca.setIndividualInfo(info);
		return ca;
	}

	private String getRegisterChannel(String deviceType) {
		String channel = null;
		if (StringUtils.isNotBlank(deviceType)) {
			if ("iphone".equals(deviceType)) {
				channel = "208000201021";
			} else if ("android".equals(deviceType)) {
				channel = "208000202021";
			}
		} else {
			channel = "208000202021";
		}
		return channel;
	}

	/**
	 * 构造注册线上线下会员方法所需传入参数
	 * 
	 * @param staffCode
	 * @param mobileNo
	 * @param password
	 * @param storeCode
	 * @param branchCode
	 * @return
	 */
	private CrtOnlineAndOfflineAcnt createOnlineAndOfflineAccountParam(
			String staffCode, String mobileNo, String storeCode,
			String branchCode, String accountCreatedChannel) {
		// 注册线上线下会员
		CrtOnlineAndOfflineAcnt param = new CrtOnlineAndOfflineAcnt();
		OnlineAndOfflineIndividualInfo info = new OnlineAndOfflineIndividualInfo();
		OnlineAndOfflineContactPoint contactPonit = new OnlineAndOfflineContactPoint();
		List<OnlineAndOfflineContactPoint> contactPointList = new ArrayList<OnlineAndOfflineContactPoint>();
		// 1：“ip/门店”说明：POS需要填“门店”，B2C业态则要填“IP”
		// 2：“操作员工号”说明：B2C采用账号，POS采用员工号
		// 3：@@为分割符
		param.setRequestIP(storeCode + "@@" + staffCode);
		// 业态类型 电器
		param.setEcoType("140000000020");
		param.setMobileNum(mobileNo);
		//手机号码验证状态 ,173000000020表示已验证
		param.setMobileNumStat("173000000020");
		param.setStore(storeCode);
		param.setBranch(branchCode);
		// 渠道
		param.setAccountCreatedChannel(accountCreatedChannel);
		
		contactPonit.setCntctPointType("143000000010");
		contactPonit.setPreferFlag("100000000010");
		contactPointList.add(contactPonit);
		info.setContactPointList(contactPointList);
		param.setIndividualInfo(info);
		return param;
	}
	
	/**
	 * 会员消费行为采集
	 * @param regisRtn
	 * @param staffCode
	 * @param mobileNo
	 */
	private void saveConsumBehavior(RegisterInfoRtn regisRtn, String staffCode, String mobileNo){
		ConsumerBehaviorDto conDto = new ConsumerBehaviorDto();
		conDto.setCustNo(regisRtn.getCustNum());
		conDto.setStaffId(staffCode);
		conDto.setPhoneNo(mobileNo);
		conDto.setBehaviorType(ConsumerBehaviorType.REGISTER);
		conDto.setBehaviorTime(System.currentTimeMillis());
		conDto.setBehaviorName("注册会员");
		storeConsumerService.upsertConsumerBehavior(conDto);
	}
	
	/**
	 * 对会员编码进行加密
	 * @param custNum 会员编码
	 * @return
	 */
	private String encryptCustNum(String custNum){
		byte[] input = custNum.getBytes(Charsets.UTF_8);
		//干扰字段
		String pwd = "snPE2YFS5J";

        byte[] data;
        String hex = null;
		try {
			data = PBECoder.encrypt(input, pwd, PBECoder.salt);
			hex = PBECoder.byte2hex(data);
		} catch (InvalidKeyException e) {
			LOGGER.error("加密custNum失败: custNum:{}, InvalidKeyException:{}", custNum, e);
		} catch (NoSuchAlgorithmException e) {
			LOGGER.error("加密custNum失败: custNum:{}, NoSuchAlgorithmException:{}", custNum, e);
		} catch (InvalidKeySpecException e) {
			LOGGER.error("加密custNum失败: custNum:{}, InvalidKeySpecException:{}", custNum, e);			
		} catch (NoSuchPaddingException e) {
			LOGGER.error("加密custNum失败: custNum:{}, NoSuchPaddingException:{}", custNum, e);
		} catch (InvalidAlgorithmParameterException e) {
			LOGGER.error("加密custNum失败: custNum:{}, InvalidAlgorithmParameterException:{}", custNum, e);
		} catch (IllegalBlockSizeException e) {
			LOGGER.error("加密custNum失败: custNum:{}, IllegalBlockSizeException:{}", custNum, e);
		} catch (BadPaddingException e) {
			LOGGER.error("加密custNum失败: custNum:{}, BadPaddingException:{}", custNum, e);
		}
		return hex;
	}
	
	public String getValidateNewRedUrl() {
		return validateNewRedUrl;
	}

	public void setValidateNewRedUrl(String validateNewRedUrl) {
		this.validateNewRedUrl = validateNewRedUrl;
	}

}
